package com.ruoyi.framework.web.method;

import java.lang.reflect.Method;
import javax.servlet.http.HttpServletRequest;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.annotation.ApiEncrypt;
import com.ruoyi.common.utils.StringUtils;

/**
 * 解密请求参数解析器
 * 
 * @author ruoyi
 */
public class DecryptedRequestBodyArgumentResolver implements HandlerMethodArgumentResolver
{
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public boolean supportsParameter(MethodParameter parameter)
    {
        Method method = parameter.getMethod();
        if (method == null)
        {
            return false;
        }
        
        // 获取类上的注解
        ApiEncrypt classAnnotation = parameter.getContainingClass().getAnnotation(ApiEncrypt.class);
        // 获取方法上的注解
        ApiEncrypt methodAnnotation = method.getAnnotation(ApiEncrypt.class);
        
        // 如果方法和类上都没有注解，则不支持
        if (classAnnotation == null && methodAnnotation == null)
        {
            return false;
        }
        
        // 优先使用方法上的注解，如果方法上没有注解，则使用类上的注解
        boolean requestDecrypt = methodAnnotation != null ? methodAnnotation.requestDecrypt() : classAnnotation.requestDecrypt();
        
        return requestDecrypt;
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
            NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception
    {
        HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
        if (request == null)
        {
            return null;
        }
        
        // 获取解密后的请求体
        String decryptedBody = (String) request.getAttribute("DECRYPTED_REQUEST_BODY");
        
        if (StringUtils.isEmpty(decryptedBody))
        {
            return null;
        }
        
        // 如果参数类型是String，直接返回解密后的数据
        if (parameter.getParameterType() == String.class)
        {
            return decryptedBody;
        }
        
        // 否则尝试将JSON字符串转换为对应的对象
        try
        {
            return objectMapper.readValue(decryptedBody, parameter.getParameterType());
        }
        catch (Exception e)
        {
            // 如果转换失败，返回null
            return null;
        }
    }
}